home *** CD-ROM | disk | FTP | other *** search
- /* obscure.c -- how to make a C source unreadable but compilable.
- Copyright (C) 1995 Sandro Sigala - <sansig@freenet.hut.fi> */
-
- /* $Id: obscure.c,v 1.27 1995/08/11 15:27:22 sandro Exp $ */
-
- /* This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-
- #include <assert.h>
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include <getopt.h>
-
- #include "lex.h"
- #include "hash.h"
- #include "misc.h"
- #include "version.h"
-
- #include "obscure.h"
-
- FILE *input_file;
- FILE *output_file;
-
- /* identifier prefix */
- static char prefix[128] = "q";
-
- /* do not change identifiers option */
- static int opt_not_change_identifiers = 0;
-
- /* make unreadable option */
- static int opt_make_unreadable = 0;
-
- /* silly words option */
- static int opt_silly = 0;
-
- /* prefix changed */
- static int opt_prefix = 0;
-
- static int opt_width = 78;
- static int opt_width_changed = 0;
-
- /* hash table for reserved identifiers */
- static struct hash_table *res_table;
-
- /* hash table for identifiers */
- static struct hash_table *id_table;
-
- /* number used for generating the identifiers */
- static int idnum = 0;
-
- static int sillynum = 0;
- static int sillyrenum = 0;
-
- /* add the identifier to the hash table and return a unique one */
-
- char *
- add_identifier (char *s)
- {
- char buf[128], *str;
-
- if (hash_table_lookup (id_table, s) == HASH_OK)
- return ((char *) hash_table_retrive_data (id_table, s));
-
- assert (hash_table_add (id_table, s) == HASH_OK);
-
- if (!opt_silly)
- sprintf (buf, "%s%d", prefix, idnum++);
- else
- {
- if (!silly_words[sillynum])
- {
- sillynum = 0;
- sillyrenum++;
- }
-
- if (!opt_prefix)
- buf[0] = '\0';
- else
- strcpy (buf, prefix);
-
- if (sillyrenum)
- {
- strcat (buf, silly_words[sillyrenum]);
- strcat (buf, "_");
- }
-
- strcat (buf, silly_words[sillynum++]);
- }
-
- str = (char *) xmalloc (strlen (buf) + 1);
- strcpy (str, buf);
- assert (hash_table_set_data (id_table, s, str) == HASH_OK);
-
- return str;
- }
-
- static int column = 0;
-
- static void
- outch (char c)
- {
- if (c == '\n')
- column = 0;
- else
- if (++column > opt_width && opt_width_changed)
- {
- putc ('\n', output_file);
- column = 1;
- }
- putc (c, output_file);
- }
-
- static void
- outstr (char *s)
- {
- if (((column += strlen (s)) > opt_width) && opt_width_changed)
- {
- if (column - strlen (s) != 0)
- putc ('\n', output_file);
- column = strlen (s);
- }
-
- while (*s)
- fputc (*s++, output_file);
- }
-
- void
- parse (void)
- {
- int tk, last_token = 0, last_char = 0;
- while ((tk = gettoken ()) != EOF)
- {
- switch (tk)
- {
- case COMMENT:
- break;
-
- case IDENTIFIER:
- {
- char *p;
- if (opt_not_change_identifiers)
- p = lex_token_buffer;
- else
- {
- if (hash_table_lookup (res_table, lex_token_buffer) == HASH_OK)
- p = lex_token_buffer;
- else
- p = add_identifier (lex_token_buffer);
-
- last_char = p[strlen (p) - 1];
-
- if (opt_make_unreadable &&
- (last_token == IDENTIFIER || last_token == NUMBER ||
- (last_token >= KW_AUTO && last_token <= KW_WHILE)))
- outch (' ');
- }
- outstr (p);
- break;
- }
-
- case NUMBER:
- if (opt_make_unreadable > 0 &&
- (last_token == IDENTIFIER || last_token == NUMBER ||
- (last_token >= KW_AUTO && last_token <= KW_WHILE)))
- outch (' ');
- outstr (lex_token_buffer);
- break;
-
- case CHARACTER: case STRING:
- outstr (lex_token_buffer);
- break;
-
- case DIRECTIVE:
- if (opt_make_unreadable && last_token != 0 &&
- last_token != DIRECTIVE && last_token != COMMENT)
- outch ('\n');
- outstr (lex_token_buffer);
- column = 0;
- break;
-
- case KW_AUTO: case KW_BREAK: case KW_CASE: case KW_CHAR:
- case KW_CONST: case KW_CONTINUE: case KW_DEFAULT: case KW_DO:
- case KW_DOUBLE: case KW_ELSE: case KW_ENUM: case KW_EXTERN:
- case KW_FLOAT: case KW_FOR: case KW_GOTO: case KW_IF:
- case KW_INT: case KW_LONG: case KW_REGISTER: case KW_RETURN:
- case KW_SHORT: case KW_SIGNED: case KW_SIZEOF: case KW_STATIC:
- case KW_STRUCT: case KW_SWITCH: case KW_TYPEDEF: case KW_UNION:
- case KW_UNSIGNED: case KW_VOID: case KW_VOLATILE: case KW_WHILE:
- if (opt_make_unreadable > 0 &&
- (last_token == IDENTIFIER || last_token == NUMBER ||
- (last_token >= KW_AUTO && last_token <= KW_WHILE)))
- outch (' ');
- outstr (lex_token_buffer);
- break;
-
- case TK_DECREMENT: outstr ("--"); break;
- case TK_INCREMENT: outstr ("++"); break;
- case TK_ADD_ASSIGN: outstr ("+="); break;
- case TK_SUB_ASSIGN: outstr ("-="); break;
- case TK_MUL_ASSIGN: outstr ("*="); break;
- case TK_DIV_ASSIGN: outstr ("/="); break;
- case TK_MOD_ASSIGN: outstr ("%="); break;
- case TK_AND_ASSIGN: outstr ("&="); break;
- case TK_OR_ASSIGN: outstr ("|="); break;
- case TK_XOR_ASSIGN: outstr ("^="); break;
- case TK_LEFT_ASSIGN: outstr ("<<="); break;
- case TK_RIGHT_ASSIGN: outstr (">>="); break;
- case TK_PTR_OP: outstr ("->"); break;
- case TK_EQ_OP: outstr ("=="); break;
- case TK_NE_OP: outstr ("!="); break;
- case TK_AND_OP: outstr ("&&"); break;
- case TK_OR_OP: outstr ("||"); break;
- case TK_GE_OP: outstr (">="); break;
- case TK_LE_OP: outstr ("<="); break;
- case TK_LEFT_OP: outstr ("<<"); break;
- case TK_RIGHT_OP: outstr (">>"); break;
- case TK_ELLIPSIS: outstr ("..."); break;
-
- default:
- outch (tk);
- }
- last_token = tk;
- }
- }
-
- void
- add_reserved_ids (void)
- {
- int i = 0;
- while (reserved_ids [i])
- hash_table_add (res_table, reserved_ids[i++]);
- }
-
- void
- add_file_to_ids (struct hash_table *table, char *fname)
- {
- FILE *f;
- char buf[255];
-
- if ((f = fopen (fname, "r")) == NULL)
- {
- fprintf (stderr, "cannot open %s\n", fname);
- exit (1);
- }
-
- while (fgets (buf, 255, f) != NULL)
- {
- if (strlen (buf) > 1)
- {
- buf[strlen (buf) - 1] = '\0';
- hash_table_add (table, buf);
- }
- }
-
- fclose (f);
- }
-
- void
- helppage (char *progname)
- {
- fprintf (stderr, "\
- %s %s - c-tools %s - Copyright (C) 1995 Sandro Sigala.\n\
- usage: %s [-huis] [-w width] [-a file] [-n file] [-p prefix]\n\
- [input [output]]\n\
- -h display this help and exit\n\
- -u make very unreadable output\n\
- -i do not change identifiers\n\
- -s use silly words instead of numbers for the identifiers\n\
- -w width set the width of the output\n\
- -a file add first the identifiers contained in this file\n\
- -n file do not change the identifiers contained in this file\n\
- -p prefix use this prefix as the prefix of the identifiers\n\
- ",
- progname, VERSION_OBSCURE, VERSION_CTOOLS, progname);
- exit (0);
- }
-
- int
- main (int argc, char **argv)
- {
- int c;
-
- id_table = hash_table_build ();
- res_table = hash_table_build ();
-
- lex_return_white_spaces = 1;
- lex_return_directives = 1;
-
- while (1)
- {
- c = getopt (argc, argv, "a:n:p:w:suih");
- if (c == EOF)
- break;
-
- switch (c)
- {
- case 'a':
- if (!opt_not_change_identifiers)
- add_file_to_ids (id_table, optarg);
- else
- fprintf (stderr, "parameter -a ignored\n");
- break;
-
- case 'n':
- if (!opt_not_change_identifiers)
- add_file_to_ids (res_table, optarg);
- else
- fprintf (stderr, "parameter -f ignored\n");
- break;
-
- case 'p':
- if (!opt_not_change_identifiers)
- {
- strcpy (prefix, optarg);
- opt_prefix = 1;
- }
- else
- fprintf (stderr, "parameter -p ignored\n");
- break;
-
- case 'u':
- opt_make_unreadable = 1;
- opt_width_changed = 1;
- lex_return_white_spaces = 0;
- break;
-
- case 'w':
- opt_width = atoi (optarg);
- opt_width_changed = 1;
- if (opt_width < 2)
- opt_width = 2;
- break;
-
- case 's':
- if (!opt_not_change_identifiers)
- opt_silly = 1;
- else
- fprintf (stderr, "parameter -w ignored\n");
- break;
-
- case 'i':
- opt_not_change_identifiers = 1;
- break;
-
- case 'h':
- case '?':
- helppage (argv[0]);
- break;
- }
- }
-
- input_file = stdin;
- output_file = stdout;
-
- if (optind < argc)
- {
- if ((argc - optind) > 2)
- helppage (argv[0]);
-
- if (strcmp (argv[optind], "-") != 0)
- input_file = fopen (argv[optind], "r");
-
- if ((argc - optind) > 1)
- if (strcmp (argv[optind + 1], "-") != 0)
- output_file = fopen (argv[optind + 1], "w");
- }
-
- if (input_file == NULL)
- {
- fprintf (stderr, "%s: cannot open input file\n", argv[0]);
- exit (1);
- }
-
- if (output_file == NULL)
- {
- fprintf (stderr, "%s: cannot open output file\n", argv[0]);
- exit (1);
- }
-
- if (!opt_not_change_identifiers)
- add_reserved_ids ();
-
- init_lex ();
-
- parse ();
-
- if (opt_make_unreadable)
- outch ('\n');
-
- done_lex ();
-
- hash_table_free (id_table);
- hash_table_free (res_table);
-
- return 0;
- }
-
- /* obscure.c ends here */
-